/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2021年5月23日
 */
package com.massyframework.beanskin.service.metadata;

import java.lang.annotation.Annotation;
import java.util.List;
import java.util.function.Predicate;

/**
 * {@link ClassMetadata}, 类元数据
 */
public interface ClassMetadata extends Metadata<Class<?>> {

    /**
     * 判断字段是否存在
     * @param fieldName 字段名
     * @return <code>true</code>存在,<code>false</code>不存在
     */
    boolean containsField(String fieldName);

    /**
     * 模块名称和类名混合后的MD5摘要
     * 
     * <p>
     * 混合方式： 模块名称:类名;
     * 
     * 不属于模块的类，其模块名称为"system".
     * @return {@link String}
     */
    String getDigest();

    /**
     * 取回所有字段名称
     * @return {@link List}
     */
    List<String> getFieldNames();

    /**
     * 取回所有方法名称
     * @return {@link List}
     */
    List<String> getMethodNames();

    /**
     * 按字段名查找字段元数据
     * @param fieldName 字段名
     * @return {@link FieldMetadata}, 无对应字段可返回null.
     */
    FieldMetadata findFieldMetadata(String fieldName);

    /**
     * 获取任意满足{@code filter}条件的字段元数据
     * @param filter {@link Predicate}, 条件过滤器
     * @return {@link FieldMetadata}, 如果没有满足要求的字段元数据，可以返回null.
     */
    FieldMetadata findFieldMetadata(Predicate<FieldMetadata> filter);


    /**
     * 按方法名称和参数查找方法
     * @param methodName 方法名称
     * @param paramTypes 参数数组
     * @return {@link MethodMetadata},无对应方法可返回null.
     */
    MethodMetadata findMethodMetadata(String methodName, Class<?>[] paramTypes);

    /**
     * 获取任意满足{@code filter}条件的方法元数据
     * @param filter {@link Predicate}, 条件过滤器
     * @return {@link MethodMetadata}, 如果没有满足要求的方法元数据，可以返回null.
     */
    MethodMetadata findMethodMetadata(Predicate<MethodMetadata> filter);

    /**
     * 获取满足{@code filter}条件的所有字段元数据
     * @param filter {@link Predicate}, 条件过滤器
     * @return {@link FieldMetadata}列表
     */
    List<FieldMetadata> getFieldMetadatas(Predicate<FieldMetadata> filter);

    /**
     * 查找注解类型为<code>annoType</code>的字段
     * @param annoType {@link Class},注解类型
     * @return {@link FieldMetadata}列表
     */
    <A extends Annotation> List<FieldMetadata> getFieldMetadatasWithAnnotation(Class<A> annoType);

    /**
     * 所有的方法元数据
     * @return {@link List}
     */
    List<MethodMetadata> getMethodMetadatas();

    /**
     * 查找注解<code>annoType</code>的方法
     * @param annoType {@link Class},注解类型
     * @return {@link List}
     */
    <A extends Annotation> List<MethodMetadata> getMethodMetadatasWithAnnotation(Class<A> annoType);


    /**
     * 按方法名称获取所有方法元数据
     * @param methodName 方法名称
     * @return {@link List}
     */
    List<MethodMetadata> getMethodMetadatas(String methodName);
}

